﻿using System;
using System.Collections.Generic;
namespace Kyoh.Lib.Collections
{
    /// <summary>インデックスとキーの両方でアクセス可能な <see cref="IDictionary{TKey, TValue}"/> インターフェースの継承インターフェースを定義します。</summary>
    /// <typeparam name="TKey">キーの型。<see cref="System.Int32"/> 以外を指定できます。</typeparam>
    /// <typeparam name="TValue">値の型。</typeparam>
    public interface IListedDictionary<TKey, TValue> : IDictionary<TKey, TValue>
    {
        /// <summary>指定された <typeparamref name="TValue"/> オブジェクトを値に持つ要素が存在するかどうかを取得します。</summary>
        /// <param name="item">検索対象のオブジェクト。</param>
        /// <returns>指定された <typeparamref name="TValue"/> オブジェクトを値に持つ要素が存在する場合は <c>true</c>。それ以外の場合は <c>false</c>。</returns>
        bool ContainsValue(TValue item);
        /// <summary>値の <typeparamref name="TValue"/> オブジェクトをすべて配列にコピーします。</summary>
        /// <param name="value">値をコピーする配列。</param>
        /// <param name="arrayIndex">コピー先の配列のオフセット。</param>
        void CopyValueTo(TValue[] value, int arrayIndex);
        /// <summary>指定された条件を満たすキーを取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{T}"/> デリゲート。</param>
        /// <returns>抽出条件を満たす <typeparamref name="TKey"/> オブジェクト。</returns>
        TKey FindKey(Predicate<TKey> predicate);
        /// <summary>指定された条件を満たすキーをすべて取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{T}"/> デリゲート。</param>
        /// <returns>抽出条件を満たすすべてのキーを格納した <see cref="IList{TKey}"/> オブジェクト。</returns>
        IList<TKey> FindKeyAll(Predicate<TKey> predicate);
        /// <summary>指定された条件を満たすキーの最初のインデックスを取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{TKey}"/> デリゲート。</param>
        /// <returns>抽出条件を満たすキーの最初のインデックスを表す <see cref="Int32"/> 値。</returns>
        int FindKeyIndex(Predicate<TKey> predicate);
        /// <summary>指定された条件を満たすキーの最後のインデックスを取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{TKey}"/> デリゲート。</param>
        /// <returns>抽出条件を満たすキーの最後のインデックスを表す <see cref="Int32"/> 値。</returns>
        int FindKeyLastIndex(Predicate<TKey> predicate);
        /// <summary>指定された条件を満たす値を取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{TValue}"/> デリゲート。</param>
        /// <returns>抽出条件を満たす <typeparamref name="TValue"/> オブジェクト。</returns>
        TValue FindValue(Predicate<TValue> predicate);
        /// <summary>指定された条件を満たす値をすべて取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{TValue}"/> デリゲート。</param>
        /// <returns>抽出条件を満たすすべての値を格納した <see cref="IList{TValue}"/> オブジェクト。</returns>
        IList<TValue> FindValueAll(Predicate<TValue> predicate);
        /// <summary>指定された条件を満たす値の最初のインデックスを取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{TValue}"/> デリゲート。</param>
        /// <returns>抽出条件を満たす値の最初のインデックスを表す <see cref="Int32"/> 値。</returns>
        int FindValueIndex(Predicate<TValue> predicate);
        /// <summary>指定された条件を満たす値の最後のインデックスを取得します。</summary>
        /// <param name="predicate">抽出条件を表す <see cref="Predicate{TValue}"/> デリゲート。</param>
        /// <returns>抽出条件を満たす値の最後のインデックスを表す <see cref="Int32"/> 値。</returns>
        int FindValueLastIndex(Predicate<TValue> predicate);
        /// <summary>要素を挿入します。</summary>
        /// <param name="index">挿入する位置を示すオフセット。</param>
        /// <param name="key">キー。</param>
        /// <param name="value">値。</param>
        void Insert(int index, TKey key, TValue value);
        /// <summary>指定されたキーの最初のインデックスを取得します。</summary>
        /// <param name="key">キー。</param>
        /// <returns>指定されたキーの最初のインデックスを表す <see cref="Int32"/> 値。</returns>
        int KeyIndexOf(TKey key);
        /// <summary>指定されたインデックスの要素を削除します。</summary>
        /// <param name="index">削除するインデックス。</param>
        void RemoveAt(int index);
        /// <summary>インデックスを指定して要素を取得します。</summary>
        /// <param name="index">インデックス。</param>
        /// <returns>指定されたインデックスの <see cref="KeyValuePair{TKey, TValue}"/> オブジェクト。</returns>
        KeyValuePair<TKey, TValue> this[int index] { get; set; }
        /// <summary>指定された値の最初のインデックスを取得します。</summary>
        /// <param name="value">値。</param>
        /// <returns>指定された値の最初のインデックスを表す <see cref="Int32"/> 値。</returns>
        int ValueIndexOf(TValue value);
        /// <summary>指定された値の最後のインデックスを取得します。</summary>
        /// <param name="value">値。</param>
        /// <returns>指定された値の最後のインデックスを表す <see cref="Int32"/> 値。</returns>
        int ValueLastIndexOf(TValue value);
    }
}
